//:C01:Wrapped.cpp
// Safe, atomic pointers.
#include <iostream>
#include <cstddef>
using namespace std;

// Simplified , Yours may have other argumets
template<class T, int sz = 1> 
class PWrap {
  T *ptr;
  public:
    class RangeError {};  // Exception class
    PWrap() {
      ptr = new T[sz];
      cout << "PWrap costructor " << endl;
    }
    ~PWrap() {
      delete[] ptr;
      cout << "PWrap destructor" << endl;
    }
    T &operator[](int i) throw(RangeError) {
      if (i >= 0 && i < sz) {
        return ptr[i];
      }
      throw RangeError();
    }
};

class Cat {
  public:
    Cat() { cout << "Cat" << endl; }
    ~Cat() { cout << "~Cat()" << endl; }
    void g() {}
};

class Dog {
  public:
    void *operator new[](size_t) {
      cout << "Allocating a Dog" << endl;
      throw 47;
    }
    void operator delete[](void *p) {
      cout << "Deallocating a Dog" << endl;
      ::operator delete[](p);
    }
};

class UseResources {
  PWrap<Cat, 3> cats;
  PWrap<Dog> dog;
  public:
    UseResources() { 
        cout << "UseResources()" << endl;
    }
    ~UseResources() {
        cout << "~UseResources()" << endl;
    }
    void f() {
        cats[1].g();
    }
};

int main(void) {
  try {
    UseResources ur;
  } catch (int) {
    cout << "inside handler" << endl;
  } catch (...) {
    cout << "inside catch(...)" << endl;
  }
}